package com.pkk.spring.cloud.service.gateway.selector;

import static com.pkk.spring.cloud.service.gateway.support.DynamicRouteConfigUtils.DYNAMIC_ROUTE_CONFIG_CLASS_NAME;

import com.pkk.spring.cloud.service.gateway.annotation.RouteDefinitionRepositoryAdviceModel;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

/**
 * 路由咨询模式导入器
 *
 * @author peikunkun
 * @version V1.0
 * @date 2021-01-15 17:30
 **/
public abstract class RouteDefinitionRepositoryAdviceModelImportSelector implements ImportSelector, EnvironmentAware {


  private Environment environment;

  /**
   * 默认没有实现的配置
   */
  protected static final String[] NO_IMPORTS = {};


  /**
   * 默认的路由定义信息持久模式的注解信息
   */
  public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";


  /**
   * 选择性的导入器
   *
   * @return java.lang.String[]
   * @Param importingClassMetadata
   * @author peikunkun
   * @date 2021/1/15 0015 下午 5:34
   * @since
   */
  @Override
  public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    //获取注解属性[@classValuesAsString不加载类,使用resource读字节码资源文件]
    AnnotationAttributes a = AnnotationAttributes
        .fromMap(importingClassMetadata.getAnnotationAttributes(DYNAMIC_ROUTE_CONFIG_CLASS_NAME, false));

    if (null == a || a.isEmpty()) {
      throw new IllegalArgumentException(String.format("动态路由没有启用配置路由储存信息"));
    }

    //获取方式
    RouteDefinitionRepositoryAdviceModel model = a.getEnum(getRouteAdviceModeAttributeName());

    //获取符合的配置bean
    String[] imports = selectImports(model);
    if (imports == null) {
      throw new IllegalArgumentException("Unknown RouteDefinitionRepositoryAdviceModel: " + model);
    }
    return imports;
  }

  /**
   * 获取路由定义持久方式的配置bean
   *
   * @return java.lang.String[]
   * @Param model
   * @author peikunkun
   * @date 2021/1/15 0015 下午 5:50
   * @since
   */
  protected abstract String[] selectImports(RouteDefinitionRepositoryAdviceModel model);


  /**
   * 由*通用类型{@code A}指定的注释的{@link AdviceMode}属性的名称。默认值为{@value #DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME}，*，但子类可以重写以进行自定义。
   */
  protected String getRouteAdviceModeAttributeName() {
    return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
  }


  /**
   * 是否启用改配置
   *
   * @return boolean
   * @author peikunkun
   * @date 2021/1/23 0023 上午 11:50
   */
  protected final boolean isEnabled() {
    return (Boolean) this.getEnvironment()
        .getProperty("penguin.cloud.dynamic.route.enabled", Boolean.class, Boolean.TRUE);
  }

  /**
   * 获取环境信息
   *
   * @return org.springframework.core.env.Environment
   * @author peikunkun
   * @date 2021/1/23 0023 上午 11:51
   */
  public Environment getEnvironment() {
    return environment;
  }

  /**
   * Set the {@code Environment} that this component runs in.
   *
   * @param environment
   */
  @Override
  public void setEnvironment(Environment environment) {
    this.environment = environment;
  }

}
